class HashTable:
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.data = [None] * self.size

    def put(self, key, data):
        hash_key = self.hash_function(key)  # 键的位置

        if self.slots[hash_key] is None:
            self.slots[hash_key] = key
            self.data[hash_key] = data
        else:
            if self.slots[hash_key] == key:
                self.data[hash_key] = data  # 替换
            else:
                next_slot = self.rehash(hash_key)
                # 这个循环是为了找到一个空槽或者找到与key相等的槽
                while self.slots[next_slot] is not None and self.slots[next_slot] != key:
                    next_slot = self.rehash(next_slot)

                if self.slots[next_slot] is None:  # 如果槽的key为None则添加一对key-value
                    self.slots[next_slot] = key
                    self.data[next_slot] = data
                else:
                    self.data[next_slot] = data  # 如果槽的key一样，则替换原来的值

    def get(self, key):
        start_slot = self.hash_function(key)

        data = None
        found = False
        stop = False
        position = start_slot

        while self.slots[start_slot] is not None and not found and not stop:
            if self.slots[position] == key:
                found = True
                data = self.data[position]
            else:
                position = self.rehash(position)
                if position == start_slot:  # 因为是取余函数，所以迟早是会绕回来的
                    stop = True

        return data

    def hash_function(self, key):
        return key % self.size

    def rehash(self, old_hash):
        return (old_hash + 1) % self.size

    def __getitem__(self, item):
        return self.get(item)

    def __setitem__(self, key, value):
        self.put(key, value)

    def __repr__(self):
        result_str = ''
        for key, value in zip(self.slots, self.data):
            if key is not None:
                result_str = result_str + f'{key}:{value},'

        return result_str

    def __len__(self):
        count = 0
        for key, value in zip(self.slots, self.data):
            if key is not None:
                count += 1

        return count


if __name__ == "__main__":
    my_dict = HashTable()
    print(my_dict.__dict__)
    print(my_dict.__class__.__name__)
    print(HashTable.__dict__)
    my_dict[222] = 'nice'
    my_dict[21] = 'world'
    print(my_dict[222])
    print(my_dict[21])
    print(my_dict)
    print(len(my_dict))